"""
Grave! Important! Важно!

Proletoj el ĉiuj landoj, unuiĝu!
Workers of the world, unite!
Пролетарии всех стран, соединяйтесь!

https://tkom.pro
"""

from django.contrib import admin
from django.contrib.admin.sites import AdminSite
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django import forms
from django.contrib.admin.models import LogEntry
import json

from siriuso.utils import get_enhavo
from siriuso.forms.widgets import LingvoInputWidget
from main.models import *


AdminSite.site_header = _('Администрирование Технокома')
AdminSite.site_title = _('Техноком')
AdminSite.empty_value_display = '-'

#admin.site.unregister(Group)


@admin.register(LogEntry)
class LogEntryAdmin (admin.ModelAdmin):
    list_display = ['action_time', 'action_flag', 'object_repr', 'user']
    list_display_links = ['action_time', 'action_flag', 'object_repr']
    list_filter = ['action_flag', 'action_time']

    search_fields = ['action_time', 'action_flag', 'object_repr', 'object_id']

    class Meta:
        model = LogEntry


# Слаг
@admin.register(SiriusoSlugo)
class SiriusoSlugoAdmin (admin.ModelAdmin):
    list_display = [field.name for field in SiriusoSlugo._meta.fields]

    class Meta:
        model = SiriusoSlugo


class UzantoCreationForm(UserCreationForm):
    """
    A form for creating new users. Includes all the required
    fields, plus a repeated password.
    """
    password1 = forms.CharField(label=_('Pasvorto'), widget=forms.PasswordInput)
    password2 = forms.CharField(label=_('Konfirmo de la pasvorto'), widget=forms.PasswordInput)

    unua_nomo = forms.CharField(widget=LingvoInputWidget(), label=_('Unua nomo'), required=True)
    dua_nomo = forms.CharField(widget=LingvoInputWidget(), label=_('Dua nomo'), required=False)
    familinomo = forms.CharField(widget=LingvoInputWidget(), label=_('Familinomo'), required=True)

    class Meta:
        model = Uzanto
        fields = ('chefa_retposhto', 'chefa_telefonanumero', 'unua_nomo', 'dua_nomo', 'familinomo')

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(_('Pasvortoj ne kongruas'))
        return password2

    def clean_unua_nomo(self):
        out = self.cleaned_data['unua_nomo']
        try:
            out = json.loads(out)
            chefa_idx = out['lingvo'][out['chefa_varianto']] if out['chefa_varianto'] in out['lingvo'] else -1
            if not len(out['enhavo']) or (chefa_idx != -1 and not out['enhavo'][chefa_idx]):
                raise forms.ValidationError(_('This field is required.'))
        except json.JSONDecodeError:
            raise forms.ValidationError(_('Недопустимые данные в JSON поле'))
        return out

    def clean_dua_nomo(self):
        out = self.cleaned_data['dua_nomo']
        try:
            out = json.loads(out)
        except json.JSONDecodeError:
            raise forms.ValidationError(_('Недопустимые данные в JSON поле'))
        return out

    def clean_familinomo(self):
        out = self.cleaned_data['familinomo']
        try:
            out = json.loads(out)
            chefa_idx = out['lingvo'][out['chefa_varianto']] if out['chefa_varianto'] in out['lingvo'] else -1
            if not len(out['enhavo']) or (chefa_idx != -1 and not out['enhavo'][chefa_idx]):
                raise forms.ValidationError(_('This field is required.'))
        except json.JSONDecodeError:
            raise forms.ValidationError(_('Недопустимые данные в JSON поле'))
        return out

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data['password1'])
        if commit:
            user.save()
        return user


class UzantoChangeForm(UserChangeForm):
    """
    A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
    """
    password = ReadOnlyPasswordHashField()

    unua_nomo = forms.CharField(widget=LingvoInputWidget(), label=_('Unua nomo'))
    dua_nomo = forms.CharField(widget=LingvoInputWidget(), label=_('Dua nomo'))
    familinomo = forms.CharField(widget=LingvoInputWidget(), label=_('Familinomo'))

    class Meta:
        model = Uzanto
        fields = ('posedanto', 'tipo', 'chefa_retposhto', 'chefa_telefonanumero', 'password', 'naskighdato',
                  'sekso', 'chefa_lingvo', 'marital_status', 'naskighlando', 'naskighregiono', 'naskighloko',
                  'loghlando', 'loghregiono', 'loghloko', 'konfirmita', 'konfirmita_hash', 'is_active',
                  'unua_nomo', 'dua_nomo', 'familinomo', 'user_permissions', 'groups', 
                  'is_admin', 'is_superuser')

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]

    def clean_unua_nomo(self):
        out = self.cleaned_data['unua_nomo']
        try:
            out = json.loads(out)
            chefa_idx = out['lingvo'][out['chefa_varianto']] if out['chefa_varianto'] in out['lingvo'] else -1
            if not len(out['enhavo']) or (chefa_idx != -1 and not out['enhavo'][chefa_idx]):
                raise forms.ValidationError(_('This field is required.'))
        except json.JSONDecodeError:
            raise forms.ValidationError(_('Недопустимые данные в JSON поле'))
        return out

    def clean_dua_nomo(self):
        out = self.cleaned_data['dua_nomo']
        try:
            out = json.loads(out)
        except json.JSONDecodeError:
            raise forms.ValidationError(_('Недопустимые данные в JSON поле'))
        return out

    def clean_familinomo(self):
        out = self.cleaned_data['familinomo']
        try:
            out = json.loads(out)
            chefa_idx = out['lingvo'][out['chefa_varianto']] if out['chefa_varianto'] in out['lingvo'] else -1
            if not len(out['enhavo']) or (chefa_idx != -1 and not out['enhavo'][chefa_idx]):
                raise forms.ValidationError(_('This field is required.'))
        except json.JSONDecodeError:
            raise forms.ValidationError(_('Недопустимые данные в JSON поле'))
        return out


@admin.register(Uzanto)
class UzantoAdmin(admin.ModelAdmin):
    form = UzantoChangeForm
    add_form = UzantoCreationForm

    list_display = ('id', 'krea_dato', 'chefa_retposhto', 'chefa_telefonanumero', 'familinomo_enhavo',
                    'unua_nomo_enhavo', 'is_active', 'konfirmita', 'konfirmita', 'chefa_lingvo', 'loghlando',
                    'loghregiono')

    filter_horizontal = ('user_permissions', 'groups')
    radio_fields = {"sekso": admin.HORIZONTAL}

    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        if db_field.name == 'user_permissions':
            qs = kwargs.get('queryset', db_field.remote_field.model.objects)
            kwargs['queryset'] = qs.select_related('content_type')
        return super().formfield_for_manytomany(db_field, request=request, **kwargs)

    def unua_nomo_enhavo(self, obj):
        return get_enhavo(obj.unua_nomo, empty_values=True)[0]
    unua_nomo_enhavo.short_description = _('Unua nomo')

    def familinomo_enhavo(self, obj):
        return get_enhavo(obj.familinomo, empty_values=True)[0]
    familinomo_enhavo.short_description = _('Familinomo')

    # fieldsets = (
    #    ('Безопасность', {'fields': ('email', 'password', 'phone')}),
    #    ('Персональная информация', {'fields': (('first_name', 'last_name', 'second_name'), 'date_of_birth',
    #                                            'sex', 'avatar', 'place_of_birth', 'residence', 'marital_status',)}),
    #    ('Социальные связи', {'fields': ('relatives', 'friends')}),
    # )
    # add_fieldsets = (
    #    (None, {
    #        'classes': ('wide',),
    #        'fields': ('email', 'password1', 'password2')}
    #     ),
    # )

    search_fields = ('id', 'chefa_retposhto', 'chefa_telefonanumero', 'familinomo', 'unua_nomo', 'uuid')
    ordering = ['id', 'chefa_retposhto', 'chefa_telefonanumero', 'familinomo', 'unua_nomo',]

    list_filter = ('is_active', 'konfirmita', 'is_admin', 'is_superuser')


@admin.register(UzantoTipo)
class UzantoTipoAdmin(admin.ModelAdmin):
    list_display = ('nomo', 'uuid',)
    exclude = ('nomo',)

    class Meta:
        model = UzantoTipo


class SpecialajGrupojFormo(forms.ModelForm):
    nomo = forms.CharField(widget=LingvoInputWidget(), label=_('Titolo'), required=True)

    class Meta:
        model = SpecialajGrupoj
        fields = ('kodo', 'nomo', 'grupoj')

    def clean_nomo(self):
        out = self.cleaned_data['nomo']
        try:
            out = json.loads(out)
            chefa_idx = out['lingvo'][out['chefa_varianto']] if out['chefa_varianto'] in out['lingvo'] else -1
            if not len(out['enhavo']) or (chefa_idx != -1 and not out['enhavo'][chefa_idx]):
                raise forms.ValidationError(_('This field is required.'))
        except json.JSONDecodeError:
            raise forms.ValidationError(_('Недопустимые данные в JSON поле'))
        return out


@admin.register(SpecialajGrupoj)
class SpecialajGrupojAdmin(admin.ModelAdmin):
    add_form = SpecialajGrupojFormo
    form = SpecialajGrupojFormo

    list_display = ('kodo', 'nomo_enhavo')
    filter_horizontal = ('grupoj',)

    def nomo_enhavo(self, obj):
        return get_enhavo(obj.nomo, empty_values=True)[0]
    nomo_enhavo.short_description = _('Nomo')
